from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from Login.models import User, ThirdPartyAccount
from home.models import  CommunityPost, Video, Comment, Like
from django.http import JsonResponse
from utils.amap_location import AMapLocation
from home.course_factory import CourseFactory
from .search_utils import SearchEngine
from .agent_search import agent_search
from rest_framework.decorators import api_view
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.conf import settings
import os
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from rest_framework.parsers import MultiPartParser, FormParser
from utils.authentication import CustomJWTAuthentication
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
import json
import math
from utils.aliyun_content_safe import check_text, check_image
from utils.llm_content_safe import llm_check_text
import logging
from .serializers import VideoSerializer
from .models import Video
from .serializers import VideoSerializer
import requests
from django.http import HttpResponse
from django.views import View
from django.db.models import Q
from .models import UserVideoHistory
from django.db.models import Count

# Create your views here.

logger = logging.getLogger(__name__)

class CommunityPostListView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]
    def get(self, request):
        posts = []
        user = request.user
        print("request.user:", user)
        print("request.user.id:", getattr(user, "id", None))
        print("request.user 类型:", type(user))
        print("is_authenticated:", getattr(user, "is_authenticated", None))
        for post in CommunityPost.objects.select_related('user').order_by('-created_at'):
            user_obj = post.user
            # 获取第三方昵称和头像
            try:
                tp = ThirdPartyAccount.objects.get(user=user_obj, provider='dingtalk')
                nickname = tp.nickname if tp.nickname else user_obj.phone
                avatar = tp.avatar_url if tp.avatar_url else ""
            except ThirdPartyAccount.DoesNotExist:
                nickname = user_obj.phone
                avatar = ""
            # 点赞数和当前用户是否已点赞
            like_count = post.likes.count()
            is_liked = post.likes.filter(user=user).exists()
            posts.append({
                "id": post.id,
                "title": post.title,
                "content": post.content,
                "images": post.images,
                "duration": post.duration,
                "pace": post.pace,
                "calorie": post.calorie,
                "created_at": post.created_at,
                "avatar": avatar,
                "nickname": nickname,
                "badge": f"Lv.{getattr(user_obj, 'level', 1)}",
                "location": "",  # 如有location字段可补充
                "like_count": like_count,
                "is_liked": is_liked,
                "user_id": user_obj.id,
            })
        return Response(posts)

    def post(self, request):
        """
        发表社区动态，集成阿里云+通义千问二级内容安全检测
        """
        user = request.user
        print("request.user:", user)
        print("request.user.id:", getattr(user, "id", None))
        print("request.user 类型:", type(user))
        print("is_authenticated:", getattr(user, "is_authenticated", None))
        title = request.data.get('title', '').strip()
        content = request.data.get('content', '').strip()
        images = request.data.get('images', [])
        duration = request.data.get('duration', '')
        pace = request.data.get('pace', '')
        calorie = request.data.get('calorie', '')
        # 文本内容审核
        for text in [title, content]:
            if text:
                ali_result = check_text(text)
                if ali_result != 'pass':
                    llm_result = llm_check_text(text)
                    if not llm_result:
                        return Response({'code': 400, 'msg': '您发表的文章不当，请重新编辑'}, status=400)
        # 敏感图片检测（只拦截涉黄、涉政、暴力）
        for img_url in images:
            if img_url and check_image(img_url):
                return Response({'code': 400, 'msg': '您发表的文章不当，请重新编辑'}, status=400)
        if not title or not content:
            return Response({'code': 400, 'msg': '参数缺失'}, status=400)
        post = CommunityPost.objects.create(
            user=user,
            title=title,
            content=content,
            images=images,
            duration=duration,
            pace=pace,
            calorie=calorie
        )
        # 获取第三方昵称和头像
        try:
            tp = ThirdPartyAccount.objects.get(user=user, provider='dingtalk')
            nickname = tp.nickname if tp.nickname else user.phone
            avatar = tp.avatar_url if tp.avatar_url else ""
        except ThirdPartyAccount.DoesNotExist:
            nickname = user.phone
            avatar = ""
        return Response({
            'code': 200,
            'msg': '动态发表成功',
            'post': {
                "id": post.id,
                "title": post.title,
                "content": post.content,
                "images": post.images,
                "duration": post.duration,
                "pace": post.pace,
                "calorie": post.calorie,
                "created_at": post.created_at.strftime('%Y-%m-%dT%H:%M:%S') if post.created_at else '',
                "avatar": avatar,
                "nickname": nickname,
                "badge": f"Lv.{getattr(user, 'level', 1)}",
                "location": "",
                "like_count": 0,
                "is_liked": False,
                "user_id": user.id,
            }
        })

def user_profile(request):
    return JsonResponse({
        "avatar": "/default-avatar.png",
        "nickname": "游客",
        "location": "未知"
    })

class LocationView(APIView):
    def get(self, request):
        ip = request.GET.get('ip')
        amap = AMapLocation()
        result = amap.get_location_by_ip(ip)
        return JsonResponse(result)

class VideoRecommendView(APIView):
    def get(self, request):
        videos = Video.objects.all()[:10]
        data = [
            {
                "id": v.id,
                "cover": v.cover,
                "duration": v.duration,
                "title": v.title,
                "author": v.author,
                "author_avatar": v.author_avatar,
                "views": v.views,
                "time": v.time,
                "video_url": v.video_url
            }
            for v in videos
        ]
        return Response(data)

class CourseContentView(APIView):
    def get(self, request):
        course_type = request.GET.get("type", "瑜伽")
        try:
            course = CourseFactory.create_course(course_type)
            content = course.get_content()
            return Response(content)
        except ValueError as e:
            return Response({"error": str(e)}, status=400)

class SearchView(APIView):
    """综合搜索视图"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.search_engine = SearchEngine()
    
    def get(self, request):
        query = request.GET.get('q', '').strip()
        category = request.GET.get('category')
        sort = request.GET.get('sort', 'relevance')
        filters = request.GET.get('filters', {})
        limit = int(request.GET.get('limit', 20))
        page = int(request.GET.get('page', 1))
        if query:
            try:
                # 智能检索：用agent_search做query扩展和RAG增强
                try:
                    agent_result = agent_search(query, category, sort, filters, limit, page)
                    # agent_result 可能是字符串或dict，需兼容处理
                    if isinstance(agent_result, str):
                        import json
                        agent_result = json.loads(agent_result)
                    results_dict = agent_result if isinstance(agent_result, dict) else {}
                except Exception as e:
                    print('agent_search异常，回退es_search:', e)
                    results_dict = self.search_engine.es_search(query, category, sort, filters, limit, page)
                merged_results = []
                for type_name, items in results_dict.items():
                    for item in items:
                        # 统一 type 字段
                        if type_name == 'posts':
                            item['type'] = 'post'
                            if 'user_username' in item:
                                item['author'] = item['user_username']
                                item.pop('user_username', None)
                            elif 'username' in item:
                                item['author'] = item['username']
                                item.pop('username', None)
                        elif type_name in ['coaches', 'trainers']:
                            item['type'] = 'coach'
                            if 'user_username' in item:
                                item['author'] = item['user_username']
                                item.pop('user_username', None)
                            elif 'username' in item:
                                item['author'] = item['username']
                                item.pop('username', None)
                        else:
                            item['type'] = type_name
                        item.pop('nickname', None)
                        item.pop('user_username', None)
                        merged_results.append(item)
                # 合并Video表的搜索结果
                video_qs = Video.objects.filter(
                    Q(title__icontains=query) |
                    Q(author__icontains=query) |
                    Q(cover__icontains=query) |
                    Q(duration__icontains=query) |
                    Q(views__icontains=query) |
                    Q(time__icontains=query)
                )
                video_data = VideoSerializer(video_qs, many=True).data
                for v in video_data:
                    v['type'] = 'recommend_video'
                    merged_results.append(v)
                print('后端 merged_results:', merged_results)  # 调试日志
                # 强相关过滤
                merged_results = filter_strict(merged_results, query)
                return Response(merged_results)
            except Exception as e:
                return Response({'error': str(e)}, status=500)
        else:
            hotwords = self.search_engine.get_hotwords(limit=10)
            return Response({
                'hotwords': hotwords
            })
    
    def post(self, request):
        query = request.data.get('query', '').strip()
        category = request.data.get('category')
        sort = request.data.get('sort', 'relevance')
        filters = request.data.get('filters', {})
        limit = int(request.data.get('limit', 20))
        page = int(request.data.get('page', 1))
        if not query:
            return Response({'error': '搜索关键词不能为空'}, status=400)
        try:
            results_dict = self.search_engine.es_search(query, category, sort, filters, limit, page)
            print('后端ES results_dict:', results_dict)  # 调试日志
            merged_results = []
            for type_name, items in results_dict.items():
                for item in items:
                    if type_name == 'posts':
                        item['type'] = 'post'
                        if 'user_username' in item:
                            item['author'] = item['user_username']
                            item.pop('user_username', None)
                        elif 'username' in item:
                            item['author'] = item['username']
                            item.pop('username', None)
                    elif type_name in ['coaches', 'trainers']:
                        item['type'] = 'coach'
                        if 'user_username' in item:
                            item['author'] = item['user_username']
                            item.pop('user_username', None)
                        elif 'username' in item:
                            item['author'] = item['username']
                            item.pop('username', None)
                    else:
                        item['type'] = type_name
                    item.pop('nickname', None)
                    item.pop('user_username', None)
                    merged_results.append(item)
            print('后端 merged_results:', merged_results)  # 调试日志
            return Response(merged_results)
        except Exception as e:
            return Response({'error': str(e)}, status=500)

class SearchSuggestionView(APIView):
    """搜索建议视图"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.search_engine = SearchEngine()
    
    def get(self, request):
        """获取搜索建议"""
        query = request.GET.get('q', '').strip()
        
        if not query:
            return Response([])
        
        try:
            suggestions = self.search_engine.get_suggestions(query, limit=8)
            return Response(suggestions)
        except Exception as e:
            return Response([], status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class SearchHotwordsView(APIView):
    """搜索热词视图"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.search_engine = SearchEngine()
    
    def get(self, request):
        """获取搜索热词"""
        try:
            hotwords = self.search_engine.get_hotwords(limit=10)
            return Response(hotwords)
        except Exception as e:
            return Response([], status=status.HTTP_500_INTERNAL_SERVER_ERROR)

class AgentSearchView(APIView):
    """Agent智能搜索视图"""
    def post(self, request):
        query = request.data.get('query', '').strip()
        category = request.data.get('category')
        sort = request.data.get('sort', 'relevance')
        filters = request.data.get('filters', {})
        limit = int(request.data.get('limit', 20))
        page = int(request.data.get('page', 1))
        if not query:
            return Response({'error': '搜索关键词不能为空'}, status=400)
        try:
            result = agent_search(query, category, sort, filters, limit, page)
            return Response({'query': query, 'result': result})
        except Exception as e:
            return Response({'error': str(e)}, status=500)

def filter_strict(results, keyword):
    keyword = keyword.strip()
    filtered = []
    for item in results:
        if keyword in item.get('title', '') or keyword in item.get('content', ''):
            filtered.append(item)
    return filtered

def get_nickname(user):
    # 只返回用户表的nickname字段
    return getattr(user, 'nickname', '') or ''

class CommentListCreateView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        post_id = request.GET.get('post_id')
        if not post_id:
            return Response({'code': 400, 'msg': '缺少post_id'}, status=400)
        comments = Comment.objects.filter(post_id=post_id, parent=None).order_by('-created_at')
        data = []
        for c in comments:
            replies = [
                {
                    'id': r.id,
                    'user_id': r.user.id,
                    'nickname': get_nickname(r.user),
                    'avatar': (ThirdPartyAccount.objects.get(user=r.user, provider='dingtalk').avatar_url if ThirdPartyAccount.objects.filter(user=r.user, provider='dingtalk').exists() and ThirdPartyAccount.objects.get(user=r.user, provider='dingtalk').avatar_url else ''),
                    'content': r.content,
                    'created_at': r.created_at,
                    'like_count': r.likes.count(),
                }
                for r in c.replies.all().order_by('created_at')
            ]
            data.append({
                'id': c.id,
                'user_id': c.user.id,
                'nickname': get_nickname(c.user),
                'avatar': (ThirdPartyAccount.objects.get(user=c.user, provider='dingtalk').avatar_url if ThirdPartyAccount.objects.filter(user=c.user, provider='dingtalk').exists() and ThirdPartyAccount.objects.get(user=c.user, provider='dingtalk').avatar_url else ''),
                'content': c.content,
                'created_at': c.created_at,
                'like_count': c.likes.count(),
                'replies': replies
            })
        return Response({'code': 200, 'comments': data})

    def post(self, request):
        user = request.user
        post_id = request.data.get('post_id')
        content = request.data.get('content', '').strip()
        parent_id = request.data.get('parent_id')
        if not post_id or not content:
            return Response({'code': 400, 'msg': '参数缺失'}, status=400)
        try:
            post = CommunityPost.objects.get(id=post_id)
        except CommunityPost.DoesNotExist:
            return Response({'code': 404, 'msg': '动态不存在'}, status=404)
        parent = None
        if parent_id:
            try:
                parent = Comment.objects.get(id=parent_id)
            except Comment.DoesNotExist:
                return Response({'code': 404, 'msg': '父评论不存在'}, status=404)
        comment = Comment.objects.create(user=user, post=post, content=content, parent=parent)
        return Response({'code': 200, 'msg': '评论成功', 'comment_id': comment.id})

class LikeView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request):
        user = request.user
        post_id = request.data.get('post_id')
        if not post_id:
            return Response({'code': 400, 'msg': '参数缺失'}, status=400)
        try:
            post = CommunityPost.objects.get(id=post_id)
        except CommunityPost.DoesNotExist:
            return Response({'code': 404, 'msg': '动态不存在'}, status=404)
        like, created = Like.objects.get_or_create(user=user, post=post, comment=None)
        if created:
            return Response({'code': 200, 'msg': '点赞成功'})
        else:
            return Response({'code': 200, 'msg': '已点赞'})

class UnlikeView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request):
        user = request.user
        post_id = request.data.get('post_id')
        comment_id = request.data.get('comment_id')
        if not (post_id or comment_id):
            return Response({'code': 400, 'msg': '参数缺失'}, status=400)
        if post_id:
            Like.objects.filter(user=user, post_id=post_id, comment=None).delete()
            return Response({'code': 200, 'msg': '取消点赞成功'})
        else:
            Like.objects.filter(user=user, post=None, comment_id=comment_id).delete()
            return Response({'code': 200, 'msg': '取消点赞成功'})

class UploadView(APIView):
    parser_classes = [MultiPartParser, FormParser]

    @method_decorator(csrf_exempt)
    def post(self, request):
        file_obj = request.FILES.get('file')
        if not file_obj:
            return Response({'success': False, 'msg': '未选择文件'}, status=400)
        try:
            # 保存到media/upload目录
            upload_dir = os.path.join(settings.MEDIA_ROOT, 'upload')
            os.makedirs(upload_dir, exist_ok=True)
            file_path = os.path.join('upload', file_obj.name)
            full_path = os.path.join(settings.MEDIA_ROOT, file_path)
            with open(full_path, 'wb+') as f:
                for chunk in file_obj.chunks():
                    f.write(chunk)
            # 构造公网可访问URL，分隔符统一为/
            url = f"{settings.PUBLIC_DOMAIN}{settings.MEDIA_URL}{file_path}".replace('\\', '/')
            return Response({'success': True, 'url': url})
        except Exception as e:
            return Response({'success': False, 'msg': f'图片上传失败: {str(e)}'}, status=500)

def get_realtime_location(request):
    """
    获取实时定位信息，返回高德API的定位数据
    """
    ip = request.GET.get('ip') or get_client_ip(request)
    amap = AMapLocation()  # 记得配置好高德API KEY
    location_data = amap.get_location_by_ip(ip)
    return JsonResponse(location_data)

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

# 运动轨迹相关接口已删除，全部迁移到sport应用

# 记得在home/urls.py中添加：
# from .views import LocationView
# path('location/', LocationView.as_view()),

class DeleteCommunityPostView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request):
        post_id = request.data.get('post_id')
        if not post_id:
            return Response({'code': 400, 'msg': '缺少post_id'}, status=400)
        try:
            post = CommunityPost.objects.get(id=post_id)
        except CommunityPost.DoesNotExist:
            return Response({'code': 404, 'msg': '动态不存在'}, status=404)
        # 用户权限校验
        if str(post.user.id) != str(request.user.id):
            return Response({'code': 403, 'msg': '无权删除他人动态'}, status=403)
        post.delete()
        return Response({'code': 200, 'msg': '删除成功'})

class RecommendListView(APIView):
    """首页推荐内容接口，使用Video表，支持多字段模糊搜索"""
    def get(self, request):
        keyword = request.GET.get('keyword', '').strip()
        if keyword:
            from django.db.models import Q
            queryset = Video.objects.filter(
                Q(title__icontains=keyword) |
                Q(author__icontains=keyword) |
                Q(cover__icontains=keyword) |
                Q(duration__icontains=keyword) |
                Q(views__icontains=keyword) |
                Q(time__icontains=keyword)
            ).order_by('-time')
        else:
            queryset = Video.objects.all().order_by('-time')
        serializer = VideoSerializer(queryset, many=True)
        return Response({'results': serializer.data})

class BilibiliImageProxyView(View):
    def get(self, request):
        url = request.GET.get('url')
        # 只允许B站图片域名，防止SSRF
        if not url or not (
            url.startswith('http://i0.hdslb.com/') or 
            url.startswith('http://i1.hdslb.com/') or 
            url.startswith('http://i2.hdslb.com/')
        ):
            return HttpResponse('Invalid image url', status=400)
        try:
            resp = requests.get(url, timeout=10)
            if resp.status_code == 200:
                content_type = resp.headers.get('Content-Type', 'image/jpeg')
                return HttpResponse(resp.content, content_type=content_type)
            else:
                return HttpResponse(f'Upstream error: {resp.status_code}', status=resp.status_code)
        except Exception as e:
            return HttpResponse(f'Proxy error: {e}', status=500)

class PersonalizedRecommendView(APIView):
    """个性化推荐接口，按用户浏览习惯排序视频"""
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]
    def get(self, request):
        user = request.user
        # 获取用户浏览历史中出现频率最高的视频id，按最近浏览和频率排序
        history = UserVideoHistory.objects.filter(user=user).order_by('-viewed_at')
        if history.exists():
            # 统计用户浏览过的视频及其浏览次数
            video_counts = history.values('video').annotate(cnt=Count('id')).order_by('-cnt', '-viewed_at')
            video_ids = [item['video'] for item in video_counts]
            # 先取用户常浏览的视频
            videos = list(Video.objects.filter(id__in=video_ids))
            # 保持顺序
            videos.sort(key=lambda v: video_ids.index(v.id))
            # 再补充未浏览过的视频
            rest_videos = Video.objects.exclude(id__in=video_ids).order_by('-time')
            videos.extend(list(rest_videos))
        else:
            # 无浏览历史，按默认顺序
            videos = Video.objects.all().order_by('-time')
        serializer = VideoSerializer(videos, many=True)
        return Response({'results': serializer.data})

class VideoViewRecordView(APIView):
    """记录用户浏览视频行为"""
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request):
        user = request.user
        video_id = request.data.get('video_id')
        if not video_id:
            return Response({'error': '缺少video_id'}, status=400)
        try:
            video = Video.objects.get(id=video_id)
        except Video.DoesNotExist:
            return Response({'error': '视频不存在'}, status=404)
        # 创建或更新浏览历史
        obj, _ = UserVideoHistory.objects.update_or_create(user=user, video=video, defaults={'viewed_at': timezone.now()})
        return Response({'msg': '浏览记录已更新'})
